Description
When an application starts, it must instantiate a CLIP process and start it. The application must then block until all of its threads (CLiP, GUI etc) terminate.
Process1Process mProcess;
mProcess.Startup();
The Startup() function recursively creates, initializes and activates all of the CLIP circuitry for the process. This is a complex procedure (the reader need not know all of the details), and is broken down into a number of asynchronous events: Prestart, Create, Integrate, Initialise, Connect, Activate (and Exit). The scheduling of these events depend on the build type (Master, Slave etc).
Ie.
- Master runs Prestart
- Master creates definitive instances of ALL circuit objects
- Master Initializes all definitive data sets
- Master Activates all local methods and threads
- Master waits for slaves to connect
- Master tells slave to start creation/initialization
- Master waits for slave to initialize
- Master starts slave (master may need to wait for a minimum number of slaves)
- Master sends jobs to active slaves
- More slaves may connect, each needs to create/initialise before it can be activated
- Slave runs Prestart
- Slaves connects to master
- Slave creates instances all its definitive circuit objects, but not slaveable objects or non-definitive objects
- Slave initializes all its definitive data sets
- Slave reports initialized to Master
- Slave waits for job
- Slave processes job
- Slave reports results back to master
It is often necessary for code to be activated before the CLIP process starts (Eg. to initialise array dimensions (calculated/read from file)). This can be done in the Prestart function (see Runtime Attribution)
bool MyProc1Process::OnPrestart()
{
FILE* fp = fopen( INI_FILE, "r" );
fscanf( fp, "%d", &gARRAY_DIM_1 );
fclose( fp );
return TRUE;
}
Whenever a GUI is being used, it is almost always necessary for the GUI thread to be started before the CLIP Process (the GUI may need to stop a slave application if it can't connect to a master). Thus the main application thread needs to create a GUI dialog and activate it (non-model) (see GUI Programming) before the call to process Startup.
CMyDlg1Dlg* dlg = new CMyDlg1Dlg();
m_pMainWnd = dlg;
dlg->Create( IDD_GUI_DIALOG );
mProcess.Startup();
To get GUI events from the GUI message pump to CLIP and vice-versa, CLIP needs to know about the GUI and the GUI about CLiP. This is achieved in two ways,
- Register the main GUI dialog with the CLiP process
- Overload the GUI dialog's message pump handler.
CMyDlg1Dlg::OnInitDialog()
{
...
CLIP::SetCallbackWindow( this->GetSafeHwnd(), this );
}
LRESULT CMyDlg1Dlg::DefWindowProc( UINT message, WPARAM wParam, LPARAM )
{
CLIP::ProcessPumpMessage( message, wParam, lParam );
return CDialog::DefWindowProc( message, wParam, lParam );
}